package com.mtoolkit.jdbc.support;

import java.sql.Connection;
import java.util.HashMap;
import java.util.Map;

import com.mtoolkit.jdbc.PersistenceException;
import com.mtoolkit.page.Page;
import com.mtoolkit.util.StringUtil;

/**
 * Jdbc template implementation for ORACLE database.
 * 
 * @author 	<a href="mailto:xishizhang@gmail.com">ZhangShixi</a>
 * @version 1.0, 2011-12-8
 * @since 	JDK1.5
 */
public class OracleJdbcTemplate extends AbstractJdbcTemplate {
	
	/**
	 * Default constructor.
	 */
	public OracleJdbcTemplate() {
	}

	/**
     * {@inheritDoc}	
     *
     * @param  conn   	 {@inheritDoc}
     * @param  keySql	 {@inheritDoc}
     * @param  insertSql {@inheritDoc}
     * @param  params 	 {@inheritDoc}
     * @param  batchSize {@inheritDoc}
     * 
     * @return {@inheritDoc}
     * 
     * @throws NullPointerException 	{@inheritDoc}
     * @throws IllegalArgumentException {@inheritDoc}
     * @throws PersistenceException		{@inheritDoc}	
     */
	@Override
	public Number[] executeKeyInsert(Connection conn, 
									 String keySql,
									 String insertSql,
									 Object[][] params, 
									 int batchSize) {
		throw new UnsupportedOperationException();
	}

	/**
	 * Builds actually execute SQL statement with specified query page 
	 * info for ORACLE database. Examples:
	 * <pre>
	 * 		String sql = 
	 * 			"select TABLE_COLUMNS from (" +
	 *				"select ROWNUM as RN, tmp.* from (" +
	 * 					"select ft.* from FIRST_TABLE ft " +
	 * 					"left join SECOND_TABLE st on ft.ID = st.ID " +
	 *					"order by ft.TABLE_COLUMN desc" +
	 * 				") tmp " +
	 *				"where ROWNUM <= {1}" +
	 *			") t " +
	 *			"where t.RN >= {0}";
	 *		
	 *		or String sql = 
	 * 			"select TABLE_COLUMNS from (" +
	 *				"select ROWNUM as RN, tmp.* from (" +
	 * 					"select ft.* from FIRST_TABLE ft " +
	 * 					"left join SECOND_TABLE st on ft.ID = st.ID " +
	 *					"order by ft.TABLE_COLUMN desc" +
	 * 				") tmp " +
	 *				"where ROWNUM <= {toIndex}" +
	 *			") t " +
	 *			"where t.RN >= {fromIndex}";
	 *
	 * 		Page page = new Page(2, 5);
	 * 		page.setTotalData(20);
	 * 		
	 * 		doFileExecuteSql(sql, page) = 
	 * 			"select TABLE_COLUMNS from (" +
	 *				"select ROWNUM as RN, tmp.* from (" +
	 * 					"select ft.* from FIRST_TABLE ft " +
	 * 					"left join SECOND_TABLE st on ft.ID = st.ID " +
	 *					"order by ft.TABLE_COLUMN desc" +
	 * 				") tmp " +
	 *				"where ROWNUM <= 10" +
	 *			") t " +
	 *			"where t.RN >= 6"; 
	 * </pre>
	 * 
	 * @param  sql  SQL statement template.
	 * @param  page query page info.
	 * 
	 * @return actually execute SQL statement witch fills query page info.
	 */
	@Override
	protected String doFillExecuteSql(String sql, Page<?> page) {
		int fromIndex = page.getFromIndex() + 1;
		int toIndex	  = page.getToIndex()   + 1;
		
		if (sql.contains("{1}") && sql.contains("{0}")) {
			return StringUtil.replaceHolderArgs(sql, fromIndex, toIndex);
		} else if (sql.contains("{toIndex}") && sql.contains("{fromIndex}")) {
			Map<String, Object> params = new HashMap<String, Object>(2, 1F);
			params.put("fromIndex", fromIndex);
			params.put("toIndex", toIndex);
			
			return StringUtil.replaceNamedArgs(sql, params);
		} else {
			throw new PersistenceException(
				  "Execute sql syntax error(maybe page parameter error): " + sql);
		}
	}
	
}

